package net.towee.client.gadgets.recentdocs;

import java.util.HashMap;
import java.util.Map;

import net.towee.client.gadgets.GadgetView;
import net.towee.client.i18n.ToweeConstants;
import net.towee.client.resources.ClientResource;
import net.towee.client.widgets.DataHelpers;
import net.towee.client.widgets.ExtFlowPanel;
import net.towee.client.widgets.SheduledInputBox;
import net.towee.client.widgets.SpanPanel;
import net.towee.model.repo.DocumentData;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasChangeHandlers;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.HasOpenHandlers;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;

public class RecentDocumentsGadgetView extends GadgetView implements RecentDocumentsGadget.Display, HasOpenHandlers<DocumentData> {
	
	private final SheduledInputBox searchInputBox;
	private final Button moreButton = new Button();
	private final ExtFlowPanel documents = new ExtFlowPanel();
	private final Map<String, Widget> documentsMap = new HashMap<String, Widget>();
	
	private int newCount = 0;
	
	@Inject
	public RecentDocumentsGadgetView(ToweeConstants constants, ClientResource resource) {
		super(constants, resource);
		addStyleName( resource.css().gadgetRecentDocuments() );
		setHeight("500px");
		
		searchInputBox = new SheduledInputBox( constants.enterSearchRequest() );
		
		createSearchBox();
		createDocumentsContainer();
		
		setHeader( constants.gadgetRecentDocument() );
	}

	private void createDocumentsContainer() {
		documents.getElement().setAttribute("documents", "");
		add( documents );
		
		moreButton.setStyleName(resource.css().moreSearchResultButton());
		moreButton.setText( constants.moreSearchResult() );
		moreButton.getElement().setAttribute("moreButton", "");
		documents.add( moreButton );
	}

	private void createSearchBox() {
		FlowPanel searchBox = new FlowPanel();
		searchBox.getElement().setAttribute("searchBox", "");
		add( searchBox );
		
		FlowPanel input = new FlowPanel();
		input.setStyleName( resource.css().roundedInputBox() );
		input.add( searchInputBox );
		searchBox.add( input );
	}

	@Override
	public HasChangeHandlers getSearchInputBox() {
		return searchInputBox;
	}

	@Override
	public String getSearchString() {
		return searchInputBox.getText();
	}

	@Override
	public HasClickHandlers getMoreResultButton() {
		return moreButton;
	}

	@Override
	public HasOpenHandlers<DocumentData> getDocumentOpener() {
		return this;
	}

	@Override
	public void clearDocuments() {
		documents.clear();
		moreButton.setVisible(true);
	}
	
	@Override
	public void showDocumentAtStart(DocumentData doc) {
		showDocument(doc, true);
	}

	@Override
	public void showDocument(DocumentData doc) {
		showDocument(doc, false);
	}
	
	public void showDocument(final DocumentData doc, boolean direction) {
		FlowPanel document = new FlowPanel();
		document.getElement().setAttribute("document", "");
		
		// Create name
		FlowPanel nameContainer = new FlowPanel();
		Anchor name = new Anchor(doc.getIdentity().getName());
		nameContainer.getElement().setAttribute("name", "");
		nameContainer.add(name);
		nameContainer.add(new SpanPanel("-"));
		nameContainer.add(new SpanPanel(doc.getIdentity().getGroup().getPrintName()));
		document.add(nameContainer);
		
		name.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				OpenEvent.fire(RecentDocumentsGadgetView.this, doc);
			}
		});
		
		// Create author and date
		SpanPanel auth = new SpanPanel( doc.getIdentity().getAuthor().getFullName() );
		Widget date = DataHelpers.formattedDateTimeWidget( doc.getUpdateDate() );
		auth.getElement().setAttribute("author", "");
		date.getElement().setAttribute("date", "");
		
		FlowPanel info = new FlowPanel();
		info.getElement().setAttribute("info", "");
		info.add(new SpanPanel( constants.author() ));
		info.add(auth);
		info.add(new SpanPanel( constants.by() ));
		info.add(date);
		document.add( info );

		// Create text
		HTML strip = new HTML(doc.getDescription());
		FlowPanel textContainer = new FlowPanel();
		textContainer.add( new SpanPanel( DataHelpers.cutString(strip.getText(), 200) ));
		textContainer.getElement().setAttribute( "text", "" );
		document.add( textContainer );
		
		// Create new label
		FlowPanel newLabel = new FlowPanel();
		newLabel.getElement().setAttribute("newLabel", "");
		document.add( newLabel );
		
		if(newCount > 0) { 
			document.getElement().setAttribute("new", "");
			newCount--;
		}
		
		// Remove old showed document
		if( documentsMap.containsKey(doc.getIdentity().getId()) )
			documentsMap.get(doc.getIdentity().getId()).removeFromParent();
		
		// Show document
		if(!direction) {
			moreButton.removeFromParent();
			documents.add(document);
			documents.add(moreButton);
		}
		else
			documents.addFirst( document );
		
		// Add to map
		documentsMap.put(doc.getIdentity().getId(), document);
	}

	@Override
	public void setNewDocumentsCount(Integer result) {
		newCount = result;
		
		if(documents.getWidgetCount() > 0) {
			for(int i=0;i<documents.getWidgetCount() && i<newCount;i++) 
				documents.getWidget(i).getElement().setAttribute("new", "");
			
			newCount = documents.getWidgetCount() > newCount ? 0 : newCount-documents.getWidgetCount();  
		}
	}

	@Override
	public void onLoadingStart() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onLoadingEnd() {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public HandlerRegistration addOpenHandler(OpenHandler<DocumentData> handler) {
		return addHandler(handler, OpenEvent.getType());
	}

	@Override
	public void noMore() {
		moreButton.setVisible(false);
	}

	@Override
	public void plusNewDocumentsCount() {
		newCount++;
	}
}
